iT邦幫忙

2026 iThome 鐵人賽

DAY 6
0
AI Engineering

30天從零打造 AI 中台自學之路系列 第 6

Day 06 - 向量資料庫選型與建置:Qdrant 環境搭建、集合規劃與 Payload 結構設計

  • 分享至 

  • xImage
  •  

在構建企業開發規範 RAG(檢索增強生成)管線時,向量資料庫(Vector Database)扮演著核心記憶庫的角色。通用大模型無法掌握企業內部最新或專屬的 Coding Style、Git 分支流程與 API 設計規範;唯有透過向量資料庫將規範文件高效索引,才能在推論時提供精準的上下文依據。

今天我們將評估企業常見的向量資料庫選型,並使用 Qdrant 完成本地容器化搭建,同時完成企業規範專用的集合(Collections)與 Metadata Payload 結構設計。


一、主流向量資料庫選型與評估

評估維度 Qdrant Milvus PGVector (PostgreSQL) Chroma
實作語言 Rust(效能與記憶體安全高) Go / C++ C (Postgres Extension) Python
部署複雜度 低(單一 Binary / 輕量 Docker) 較高(依賴 etcd、MinIO 等元件) 極低(直接沿用既有 PG 集群) 極低(適合本地嵌入式開發)
Metadata 過濾能力 極強(支援豐富 Payload 索引) 強(依賴標準 SQL 語法) 基礎
資源消耗 輕量、記憶體管理優秀 中等偏高(適合超大規模分散式) 視既有 DB 負載而定 極輕量
生產環境適用度 高(企業獨立部署首選) 高(超大規模分散式首選) 高(架構輕量化首選) 偏低(較適合 PoC 實驗階段)
  • 本專案決策:選擇 Qdrant。其採用 Rust 編寫,推論與過濾速度極快,且 Payload 結構支援非常精準的 JSON 欄位篩選,極度契合開發規範需要根據「語言(Language)」、「專案版本(Version)」、「模組(Category)」動態過濾的場景。

二、Qdrant 容器化環境搭建

使用 Docker 建立具備資料持久化(Data Persistence)的 Qdrant 服務。

建立 docker-compose.qdrant.yml

version: '3.8'

services:
  qdrant:
    image: qdrant/qdrant:v1.9.0
    container_name: enterprise_qdrant
    restart: always
    ports:
      - "6333:6333"   # REST API 介面與 Web UI
      - "6334:6334"   # gRPC 高效傳輸介面
    volumes:
      - ./qdrant_storage:/qdrant/storage
    environment:
      - QDRANT__SERVICE__ENABLE_CORS=true

啟動服務:

docker compose -f docker-compose.qdrant.yml up -d

啟動後,可使用瀏覽器開啟 http://localhost:6333/dashboard,進入 Qdrant 內建的視覺化管理介面(Web Dashboard)。

三、企業開發規範集合(Collection)與 Payload 結構設計

為了讓 RAG 檢索時能快速縮小範圍,避免「Python 規範與 Java 規範混淆」,必須嚴格設計 Payload Metadata。

1. Payload 欄位規劃

{
  "doc_id": "GUID 或文件識別碼",
  "title": "章節或規則標題(例如:RESTful API 命名規範)",
  "category": "分類(例如:coding_style, git_flow, api_schema, security)",
  "language": "適用程式語言(例如:python, typescript, java, all)",
  "version": "適用版本(例如:v1.2.0)",
  "source_url": "內部文件 Wiki / Git 連結(用於回覆出處標註)",
  "content": "切塊後的文字與程式碼區塊內容"
}

2. 初始化集合與索引建立腳本

安裝 Python Client:

pip install qdrant-client

建立 init_qdrant.py,配置集合向量維度(以即將採用的 1024 維開源 Embedding 模型為例),並為關鍵欄位建立 Payload Index 以加速後續條件過濾:

from qdrant_client import QdrantClient
from qdrant_client.http import models

# 初始化客戶端(連接本地 6333 埠)
client = QdrantClient(url="http://localhost:6333")

COLLECTION_NAME = "enterprise_dev_standards"

def setup_vector_store():
    # 1. 檢查集合是否存在,若不存在則建立
    collections = client.get_collections().collections
    collection_names = [col.name for col in collections]
    
    if COLLECTION_NAME in collection_names:
        print(f"集合 [{COLLECTION_NAME}] 已存在,略過建立步驟。")
        return

    print(f"正在建立集合: {COLLECTION_NAME}...")
    client.create_collection(
        collection_name=COLLECTION_NAME,
        vectors_config=models.VectorParams(
            size=1024,  # 向量維度需與 Embedding 模型嚴格一致
            distance=models.Distance.COSINE  # 餘弦相似度
        ),
        # 啟用 HNSW 索引優化檢索吞吐
        hnsw_config=models.HnswConfigDiff(
            m=16,
            ef_construct=100
        )
    )

    # 2. 建立 Payload 索引,加速精準 Metadata 過濾
    print("正在建立 Payload 篩選索引...")
    indexed_fields = [
        ("category", models.PayloadSchemaType.KEYWORD),
        ("language", models.PayloadSchemaType.KEYWORD),
        ("version", models.PayloadSchemaType.KEYWORD)
    ]

    for field_name, field_type in indexed_fields:
        client.create_payload_index(
            collection_name=COLLECTION_NAME,
            field_name=field_name,
            field_schema=field_type
        )

    print(f"集合 [{COLLECTION_NAME}] 初始化完成,各項 Payload 索引建立完畢!")

if __name__ == "__main__":
    setup_vector_store()

四、向量庫操作與過濾查詢驗證

撰寫 verify_qdrant.py,模擬寫入一筆開發規範並執行帶 Metadata 過濾條件的向量檢索:

import numpy as np
from qdrant_client import QdrantClient
from qdrant_client.http import models

client = QdrantClient(url="http://localhost:6333")
COLLECTION_NAME = "enterprise_dev_standards"

# 1. 模擬插入一筆開發規範向量
mock_vector = np.random.rand(1024).tolist()

client.upsert(
    collection_name=COLLECTION_NAME,
    points=[
        models.PointStruct(
            id=1,
            vector=mock_vector,
            payload={
                "doc_id": "REST-001",
                "title": "RESTful 資源路徑命名指引",
                "category": "api_schema",
                "language": "all",
                "version": "v1.0",
                "source_url": "[https://wiki.corp.internal/standards/api-naming](https://wiki.corp.internal/standards/api-naming)",
                "content": "所有 API 端點路徑必須使用複數名詞與小寫字母,例如 /api/v1/users,嚴禁使用動詞。"
            }
        )
    ]
)
print("測試向量寫入成功!")

# 2. 帶條件的過濾查詢測試
query_vector = np.random.rand(1024).tolist()

search_result = client.search(
    collection_name=COLLECTION_NAME,
    query_vector=query_vector,
    query_filter=models.Filter(
        must=[
            models.FieldCondition(
                key="category",
                match=models.MatchValue(value="api_schema")
            )
        ]
    ),
    limit=1
)

print("\n--- 過濾檢索結果 ---")
for hit in search_result:
    print(f"評分 (Score): {hit.score:.4f}")
    print(f"標題: {hit.payload['title']}")
    print(f"內容: {hit.payload['content']}")

五、中台知識庫架構注意事項

向量維度一致性:VectorParams 中的 size 必須與後續選用的 Embedding 模型完全相符(例如 BGE-Large 為 1024 維,OpenAI text-embedding-3-small 為 1536 維),一旦建立即無法中途變更。

Payload 索引效益:若未針對 category 或 language 建立 Payload 索引,隨著企業文件累積到數萬筆時,帶條件的混合篩選將退化為全表暴力掃描,拖慢 RAG 檢索延遲。

明日進度

向量資料庫與 Metadata 規範已就位。明天 Day 07 我們將進入第一週的最後一天:Embedding 與 Reranker 模型落地,實測開源 Embedding 模型在技術文件上的語義表現,並在本地部署 Cross-Encoder Reranker 服務。


上一篇
Day 05 - 中台核心 Gateway 基礎骨架:基於 FastAPI 實作路由、API Key 驗證與請求標準化
下一篇
Day 07 - Embedding 與 Reranker 模型落地:開源 Embedding 評測與本地 Cross-Encoder 部署
系列文
30天從零打造 AI 中台自學之路8
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言